<template>
  <a-modal
    v-model:visible="visible"
    centered
    :title="title"
    :width="600"
    :mask-closable="false"
    :after-close="handleCancel"
    :ok-button-props="{ loading: submitting }"
    @ok="handleSubmit"
  >
    <a-form ref="FormRef" :model="formFields" :rules="formRules" :label-col="{ style: { width: '80px' } }">
      <a-form-item label="否词范围" name="scopeType">
        <a-radio-group
          v-model:value="formFields.scopeType"
          :disabled="formData.scopeTypeDisable"
          :options="scopeTypeOptions"
        />
      </a-form-item>
      <a-form-item label="匹配模式" name="matchType">
        <a-radio-group v-model:value="formFields.matchType" :options="matchTypeOptions" />
      </a-form-item>
      <a-form-item label="关键词" name="orderWordId" v-if="shouldUnitMatchType">
        <a-select
          allow-clear
          :disabled="formData.keywordDisable"
          placeholder="请选择关键词"
          :options="keywordOptions"
          label-in-value
          show-search
          :fieldNames="{ label: 'word', value: 'orderWordId' }"
          v-model:value="keywordValue"
        />
      </a-form-item>
      <a-form-item label="否词" class="flex-1" name="name">
        <a-input v-model:value.trim="formFields.name" placeholder="请输入否词" />
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup name="NegationUpdater">
import { computed, ref, UnwrapRef } from 'vue'
import { useVModel } from '@vueuse/core'
import type { FormInstance } from 'ant-design-vue'
import { toLabelValue } from '@/utils'
import { MatchTypeKeyMap, ScopedTypeKeyMap } from '@/core/mapper/negative'
import { Mode } from '@/core/interfaces/common'
import { omit } from 'lodash-es'
import { MatchTypeEnum, ScopeTypeEnum } from '@/core/enums/negative'
import type { NegativeWord } from '@/core/interfaces/negative'
import type { Creative } from '@/core/interfaces/promotion'
import { useNegativeWords } from '@/views/promotion/hooks/useNegativeWords'
import { Rule } from 'ant-design-vue/es/form'
import type { CampaignIds } from '@/core/interfaces/campaign'

interface Props {
  show: boolean
  submitting: boolean
  data: Partial<NegativeWord>
  formData: UnwrapRef<ReturnType<typeof useNegativeWords>['formData']>
  keywordOptions?: Creative[]
  campaignIds: Partial<CampaignIds>
  mode: Mode
}

interface Emits {
  (e: 'on-submit'): void
  (e: 'update:show'): void
  (e: 'update:data'): void
}

const props = withDefaults(defineProps<Props>(), {
  show: false,
  submitting: false,
  keywordOptions: () => [],
  mode: Mode.create
})
const FormRef = ref<FormInstance>()
const emit = defineEmits<Emits>()
const visible = useVModel(props, 'show', emit)
const formFields = useVModel(props, 'data', emit)
const scopeTypeOptions = toLabelValue(omit(ScopedTypeKeyMap, ScopeTypeEnum.All))
const matchTypeOptions = toLabelValue(omit(MatchTypeKeyMap, MatchTypeEnum.All))

const shouldUnitMatchType = computed(() => {
  return formFields.value.scopeType === ScopeTypeEnum.Unit
})
const title = computed(() => {
  return props.mode === Mode.create ? '新增否词' : '编辑否词'
})

const keywordValue = computed({
  set(data?: { label: Creative['word']; value: Creative['orderWordId'] }) {
    if (data) {
      const record = props.keywordOptions.find((item) => item.orderWordId === data.value)
      formFields.value.orderWordId = data.value
      formFields.value.keyword = data.label
      formFields.value.groupId = record?.groupId
      formFields.value.campaignId = record?.campaignId
    } else {
      formFields.value.orderWordId = undefined
      formFields.value.keyword = ''
      formFields.value.groupId = undefined
      formFields.value.campaignId = undefined
    }
  },
  get() {
    if (formFields.value.keyword && formFields.value.orderWordId) {
      return {
        label: formFields.value.keyword,
        value: formFields.value.orderWordId
      }
    } else {
      return undefined
    }
  }
})

const formRules = computed(() => {
  return {
    scopeType: [
      {
        required: true,
        trigger: 'blur',
        validator: checkScopeType
      }
    ],
    matchType: [
      {
        required: true,
        message: '请选择匹配模式',
        trigger: 'blur'
      }
    ],
    name: [
      {
        required: true,
        message: '请输入否词',
        trigger: 'blur'
      }
    ],
    orderWordId: [
      {
        required: shouldUnitMatchType.value,
        trigger: 'blur',
        validator: checkKeyword
      }
    ]
  }
})

// 计划否词必须判断campaignId是否存在
const shouldCampaignIds = computed(() => {
  return props.campaignIds?.pcCampaignId || props.campaignIds?.wapCampaignId || props.campaignIds?.pcWapCampaignId
})

async function checkKeyword(_: Rule, value: Creative['orderWordId']) {
  const record = props.keywordOptions.find((item) => item.orderWordId === value)
  if (!value) {
    return Promise.reject('请选择关键词')
  } else if (record?.groupId) {
    return Promise.resolve()
  } else {
    return Promise.reject('关键词还未添加创意')
  }
}

async function checkScopeType(_: Rule, value: ScopeTypeEnum) {
  if (!value) {
    return Promise.reject('请选择否词范围')
  } else if (!shouldCampaignIds.value) {
    return Promise.reject('关键词还未添加创意')
  } else {
    return Promise.resolve()
  }
}

function handleSubmit() {
  FormRef.value?.validate().then(() => {
    emit('on-submit')
  })
}

function handleCancel() {
  FormRef.value?.resetFields()
  visible.value = false
}
</script>
